Skip to content

Cmd+drag uses intersection selection, same as normal drag#12

Merged
kaznaan merged 1 commit intogray/frame-body-drag-movesfrom
gray/command-drag-intersection
Mar 2, 2026
Merged

Cmd+drag uses intersection selection, same as normal drag#12
kaznaan merged 1 commit intogray/frame-body-drag-movesfrom
gray/command-drag-intersection

Conversation

@graycrawford
Copy link
Copy Markdown
Collaborator

Removes the isWrapping check so Cmd/Ctrl+drag selects assets by intersection instead of requiring full enclosure. Only frames still require full enclosure regardless of modifier keys.

Removes the isWrapping check so Cmd/Ctrl+drag selects assets by
intersection instead of requiring full enclosure. Only frames
still require full enclosure regardless of modifier keys.

Made-with: Cursor
@cursor
Copy link
Copy Markdown

cursor Bot commented Mar 2, 2026

PR Summary

Medium Risk
Changes core selection hit-testing semantics for brush selection, which can affect user workflows and edge cases around partial overlaps. The change is localized but impacts a frequently used interaction path.

Overview
Cmd/Ctrl brush selection now behaves like standard brush selection by allowing intersection-based hits when shapes aren’t fully enclosed.

Frames remain enclosure-only: if the brush doesn’t fully contain a frame’s bounds, it’s treated as a miss and skips edge hit-testing.

Written by Cursor Bugbot for commit 3b055f0. This will update automatically on new commits. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Dead code: isWrapping and its dependencies are unused
    • Removed the unused isWrapMode class property, its initialization in onEnter, and the unused ctrlKey and isWrapping variables in hitTestShapes.

Create PR

Or push these changes by commenting:

@cursor push 64a168bd04
Preview (64a168bd04)
diff --git a/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts b/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts
--- a/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts
+++ b/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts
@@ -22,7 +22,6 @@
 
 	initialSelectedShapeIds: TLShapeId[] = []
 	excludedShapeIds = new Set<TLShapeId>()
-	isWrapMode = false
 
 	viewportDidChange = false
 	cleanupViewportChangeReactor() {
@@ -33,8 +32,6 @@
 		const { editor } = this
 		const altKey = editor.inputs.getAltKey()
 
-		this.isWrapMode = editor.user.getIsWrapMode()
-
 		this.viewportDidChange = false
 
 		let isInitialCheck = true
@@ -114,18 +111,14 @@
 	}
 
 	private hitTestShapes() {
-		const { editor, excludedShapeIds, isWrapMode } = this
+		const { editor, excludedShapeIds } = this
 		const originPagePoint = editor.inputs.getOriginPagePoint()
 		const currentPagePoint = editor.inputs.getCurrentPagePoint()
 		const shiftKey = editor.inputs.getShiftKey()
-		const ctrlKey = editor.inputs.getCtrlKey()
 
 		// We'll be collecting shape ids of selected shapes; if we're holding shift key, we start from our initial shapes
 		const results = new Set(shiftKey ? this.initialSelectedShapeIds : [])
 
-		// In wrap mode, we need to completely enclose a shape to select it
-		const isWrapping = isWrapMode ? !ctrlKey : ctrlKey
-
 		// Set the brush to contain the current and origin points
 		const brush = Box.FromPoints([originPagePoint, currentPagePoint])

// If we're in wrap mode and the brush did not fully encloses the shape, it's a miss
// We also skip frames unless we've completely selected the frame.
if (isWrapping || editor.isShapeFrame(shape)) {
if (editor.isShapeFrame(shape)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code: isWrapping and its dependencies are unused

Low Severity

After removing isWrapping from the condition on line 197, the variable isWrapping (line 127) is now computed but never read. This also makes ctrlKey (line 121), the isWrapMode class property (line 25), its initialization in onEnter (line 36), its destructuring (line 117), and the comment on line 126 all dead code. These should be cleaned up to avoid confusing future readers.

Additional Locations (2)

Fix in Cursor Fix in Web

@kaznaan kaznaan changed the base branch from luma/v4.4.x to gray/frame-body-drag-moves March 2, 2026 18:30
@kaznaan kaznaan merged commit 411e4c6 into gray/frame-body-drag-moves Mar 2, 2026
6 of 10 checks passed
kaznaan added a commit that referenced this pull request Mar 2, 2026
* Dragging on frame body always moves the frame

Made-with: Cursor

* Remove unused didHitGridLabel property and grid label detection logic

* Cmd+drag uses intersection selection, same as normal drag (#12)

Removes the isWrapping check so Cmd/Ctrl+drag selects assets by
intersection instead of requiring full enclosure. Only frames
still require full enclosure regardless of modifier keys.

Made-with: Cursor

* Remove unnecessary workaround

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Kazuho Okui <kazuho@lumalabs.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants